extensions/gggl{,-lies}.c: fix conversions u16 <-> u8
authorMassimo Valentini <mvalentini@src.gnome.org>
Sat, 14 Jul 2012 15:07:38 +0000 (17:07 +0200)
committerMassimo Valentini <mvalentini@src.gnome.org>
Sat, 14 Jul 2012 15:07:38 +0000 (17:07 +0200)
u16 maximum value is 0x10000 - 1 == (0x100 - 1) (0x100 + 1)
u8 maximum value is 0x100 - 1
thus the direct conversion requires multiplication/division per
0x100+1

division per 0x100+1 is implemented using 1 term of (1 + x)^-1
MacLaurin expansion

(1+x)^-1 == 1 + (-1) x

a * (1 + 1/256)^-1 * (256^-1) == (a - a / 256) / 256

with integer division rounded toward the nearest.

extensions/gggl-lies.c
extensions/gggl.c

index 450fd752a0e490c5dd481ffbeb0e5445175924b8..7f99b00ab2de99cb305170fbb98efbe7118fff25 100644 (file)
@@ -342,7 +342,8 @@ conv_16_8 (unsigned char *src, unsigned char *dst, long samples)
 
   while (n--)
     {
-      (*(unsigned char *) dst) = (*(unsigned short *) src) >> 8;
+#define div_257(a) ((((a)+128)-(((a)+128)>>8))>>8)
+      (*(unsigned char *) dst) = div_257 (*(unsigned short *) src);
       dst                     += 1;
       src                     += 2;
     }
@@ -356,7 +357,7 @@ conv_8_16 (unsigned char *src, unsigned char *dst, long samples)
 
   while (n--)
     {
-      (*(unsigned short *) dst) = (*(unsigned char *) src) << 8;
+      (*(unsigned short *) dst) = ((*(unsigned char *) src) << 8) | *src;
       dst                      += 2;
       src                      += 1;
     }
index c530988d002092fff13a6395ababd1b36a1a0ce2..307c574949d1d1d4ccbe8a31010b39a8fb758e41 100644 (file)
@@ -380,7 +380,8 @@ conv_16_8 (unsigned char *src, unsigned char *dst, long samples)
 
   while (n--)
     {
-      (*(unsigned char *) dst) = (*(unsigned short *) src) >> 8;
+#define div_257(a) ((((a)+128)-(((a)+128)>>8))>>8)
+      (*(unsigned char *) dst) = div_257 (*(unsigned short *) src);
       dst                     += 1;
       src                     += 2;
     }
@@ -394,7 +395,7 @@ conv_8_16 (unsigned char *src, unsigned char *dst, long samples)
 
   while (n--)
     {
-      (*(unsigned short *) dst) = (*(unsigned char *) src) << 8;
+      (*(unsigned short *) dst) = ((*(unsigned char *) src) << 8) | *src;
       dst                      += 2;
       src                      += 1;
     }